#include "input_paral_fun_MR.h"

void init_input_paral_MR_context(struct input_paral_MR_context *mr_ctx, std::string fun_str, struct paral_py_context *ctx)
{
    mr_ctx->identifier_str = "";
    mr_ctx->function_str = fun_str;
    mr_ctx->function_str_index = 0;

    mr_ctx->fun_table = ctx->fun_table;

    mr_ctx->remain_str_arr.push_back("if");
    mr_ctx->remain_str_arr.push_back("for");
    mr_ctx->remain_str_arr.push_back("in");
    mr_ctx->remain_str_arr.push_back("else");
    mr_ctx->remain_str_arr.push_back("while");
    mr_ctx->remain_str_arr.push_back("input_central_paral");

    // 括号和冒号
    mr_ctx->remain_str_arr.push_back("(");
    mr_ctx->remain_str_arr.push_back(")");
    mr_ctx->remain_str_arr.push_back(":");
    mr_ctx->remain_str_arr.push_back(",");
}

char get_char(struct input_paral_MR_context *mr_ctx)
{
    char return_char;

    if (mr_ctx->function_str_index >= mr_ctx->function_str.length())
    {
        // 超过边界，返回NULL
        return NULL;
    }

    // 没有超过范围
    return_char = mr_ctx->function_str[mr_ctx->function_str_index];
    (mr_ctx->function_str_index)++;

    return return_char;
}

void print_token_of_input_paral_fun_MR(int type)
{
    if (type == paral_py_language_tok_var)
    {
        printf("paral_py_language_tok_var");
    }
    else if (type == paral_py_language_tok_op)
    {
        printf("paral_py_language_tok_op");
    }
    else if (type == paral_py_language_tok_gramma)
    {
        printf("paral_py_language_tok_gramma");
    }
    else if (type == paral_py_language_tok_tab)
    {
        printf("paral_py_language_tok_tab");
    }
    else if (type == paral_py_language_tok_unknow)
    {
        printf("paral_py_language_tok_unknow");
    }
    else if (type == paral_py_language_tok_eof)
    {
        printf("paral_py_language_tok_eof");
    }
}

void print_paral_py_express_token_arr(std::vector<struct paral_py_tok_basic_info> arr)
{

    std::cout << "express=====:" << std::endl;
    // 打印所有的内容
    int i;
    for (i = 0; i < arr.size(); i++)
    {
        // 首先打印类型
        print_token_of_input_paral_fun_MR(arr[i].paral_py_token_type);
        // 逗号
        std::cout << " # " << arr[i].tok_str << std::endl;
    }

    std::cout << "=====" << std::endl;
}


void print_paral_py_tok_basic_info(struct paral_py_tok_basic_info info){
    // 首先打印类型
    print_token_of_input_paral_fun_MR(info.paral_py_token_type);
    // 逗号
    std::cout << " ## " << info.tok_str << std::endl;
}


struct pre_process_report input_paral_pre_analysis(std::vector<std::vector<struct paral_py_tok_basic_info>> all_code_token)
{
    struct pre_process_report return_report;
    return_report.can_trans = false;

    int i;
    int j;
    // 首先遍历，判断item=的模式
    for (i = 0; i < all_code_token.size(); i++)
    {
        std::vector<struct paral_py_tok_basic_info> a_line = all_code_token[i];
        for (j = 0; j < a_line.size(); j++)
        {
            struct paral_py_tok_basic_info info;
            info = a_line[j];
            // 首先找到item
            if (info.tok_str == "item")
            {
                if (j >= all_code_token[i].size() - 1)
                {
                    continue;
                }
                else
                {
                    // 查看后面一项是不是等号
                    if (a_line[j + 1].tok_str == "=")
                    {
                        // 不合法
                        return return_report;
                    }
                }
            }
        }
    }

    // 然后判断share[]=的模式
    for(i = 0; i < all_code_token.size(); i++){
        std::vector<struct paral_py_tok_basic_info> a_line = all_code_token[i];
        for (j = 0; j < a_line.size(); j++)
        {
            struct paral_py_tok_basic_info info;
            info = a_line[j];
            // 首先找到item
            if (info.tok_str.find("share[") == 0)
            {
                if (j >= all_code_token[i].size() - 1)
                {
                    continue;
                }
                else
                {
                    // 查看后面一项是不是等号
                    if (a_line[j + 1].tok_str == "=")
                    {
                        // 不合法
                        return return_report;
                    }
                }
            }
        }
    }

    std::string result_str_left = "";
    std::string result_str_right = "";

    // 第二次遍历，找到return模式
    for (i = 0; i < all_code_token.size(); i++)
    {
        for (j = 0; j < all_code_token[i].size(); j++)
        {
            // 查看字符串开头
            if (all_code_token[i][j].tok_str.find("result[") == 0)
            {
                // 如果result之前已经出现了一次，暂时不支持复杂的情况
                if (result_str_left != "")
                {
                    printf("not support multi codes about result\n");
                    return return_report;
                }

                result_str_left = all_code_token[i][j].tok_str;

                // std::cout <<  "result_str_left:" << result_str_left << std::endl;

                // 看看下一个是不是等号，不是等号说明有问题
                if (all_code_token[i][j + 1].tok_str != "=")
                {
                    // 没有等号
                    printf("read result\n");
                    return return_report;
                }

                // 遍历后面的内容，查看有没有result
                int k;
                for (k = j + 1; k < all_code_token[i].size(); k++)
                {
                    if (all_code_token[i][k].tok_str.find("result[") == 0)
                    {
                        if (result_str_right != "")
                        {
                            printf("not support multi result in right\n");
                            return return_report;
                        }

                        result_str_right = all_code_token[i][k].tok_str;

                        // 查看两侧是不是相等的
                        if (result_str_right != result_str_left)
                        {
                            printf("read result\n");
                            return return_report;
                        }

                        // 两侧不是相等的
                        // 查看前后的除了等号的运算符
                        if (k >= all_code_token[i].size() - 1)
                        {
                            // 查看前面一个运算符
                            if (all_code_token[i][k - 1].tok_str == "=")
                            {
                                printf("no op!\n");
                                return return_report;
                            }
                            else
                            {
                                return_report.op_str = all_code_token[i][k - 1].tok_str;
                            }
                        }
                        else
                        {
                            // 查看前后
                            if (all_code_token[i][k - 1].tok_str == "=")
                            {
                                // 前面是等号就看后面
                                return_report.op_str = all_code_token[i][k + 1].tok_str;
                            }
                            else
                            {
                                // 前后必须相等
                                if (all_code_token[i][k - 1].tok_str != all_code_token[i][k + 1].tok_str)
                                {
                                    printf("no effective op\n");
                                    return return_report;
                                }
                                else
                                {
                                    return_report.op_str = all_code_token[i][k - 1].tok_str;
                                }
                            }
                        }
                    }
                }

                // 遍历之后发现没有result
                if (result_str_right == "")
                {
                    std::cout << "no result" << std::endl;
                    //返回
                    return_report.op_str = "None";
                }

                // 当前行已经分析完了，不用再分析了
                break;
            }
        }
    }

    // 所有都遍历完，发现，检查一下result有没有找到
    // 找到了就应该没有任何问题了
    if (result_str_left != "")
    {
        return_report.can_trans = true;
    }

    return return_report;
}